# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2005-2006 CamptoCamp
# Copyright (c) 2006-2010 OpenERP S.A
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
##############################################################################

import os, time
from datetime import datetime, timedelta
from openerp.osv import osv, fields
from openerp.tools.translate import _
from openerp.report import report_sxw
import locale
from mx import DateTime as dt
from PIL.TiffImagePlugin import DATE_TIME
from mx.Tools.mxTools.mxTools import sign
from array import array
locale.setlocale(locale.LC_ALL, '')
from openerp.tools import float_round, float_is_zero, float_compare

class receiving_report_pdf(report_sxw.rml_parse):
    _name = 'receiving.report.pdf'
    
    
    def _search_data(self, cr, uid, ids, data_obj, val_data, filter_selection, default_from, default_to, input_from, input_to, selection_ids, context=None):
        #Out Default Value
        data_header = ''
        data_ids = []
        #Declaration

        if context is None:
            context = {}
            
#         special_case = 'special_case' in context and context['special_case'] or False  
        if filter_selection == 'all_vall':
            data_ids = data_obj.search(cr, uid, val_data, order='id ASC')
        if filter_selection == 'def':
            data_found = False 
            if default_from and data_obj.browse(cr, uid, default_from) and data_obj.browse(cr, uid, default_from).name:
                default_from_header = data_obj.browse(cr, uid, default_from).name
                data_found = True
                val_data.append(('name', '>=', default_from_header)) 
            if default_to and data_obj.browse(cr, uid, default_to) and data_obj.browse(cr, uid, default_to).name:
                default_to_header = data_obj.browse(cr, uid, default_to).name
                data_found = True
                val_data.append(('name', '<=', default_to_header)) 
            if data_found:
                data_header = '"' + default_from_header + '" - "' + default_to_header + '"'
                data_ids = data_obj.search(cr, uid, val_data, order='id ASC') 
        if filter_selection == 'input':
            data_found = False
            if input_from:     
                data_ids_from = data_obj.search(cr, uid, [('name','=ilike',input_from + '%')], order="name", limit=1)
                if data_ids_from:
                    input_from_name = data_obj.browse(cr, uid, data_ids_from[0]).name
  
                    data_found = True
                    val_data.append(('name', '>=', input_from_name))
            if input_to:    
                data_ids_to = data_obj.search(cr, uid, [('name','=ilike', input_to + '%')], order="name desc", limit=1)
                if data_ids_to:
                    input_to_name = data_obj.browse(cr, uid, data_ids_to[0]).name
                    data_found = True
                    val_data.append(('name', '<=', input_to_name))
            data_header = '"' + input_from + '" - "' + input_to + '"'
            if data_found:
                data_ids = data_obj.search(cr, uid, val_data, order='id ASC')
        if filter_selection == 'selection':
            if selection_ids:
                sel_ids = '' 
                for sel in  data_obj.browse(cr, uid, selection_ids):
                    sel_ids += ('"%s",')%(sel.name,) 
                data_header = '[' + sel_ids +']'
                data_ids =selection_ids
                
                data_ids = data_ids
                data_header = data_header
                
        return data_header, data_ids

    
    def set_context(self, objects, data, ids, context=None):
        new_ids = ids
        if context is None:
            context = {}
        
        purchase_orderline_obj    = self.pool.get('purchase.order.line') 
        purchase_order_obj      = self.pool.get('purchase.order')
        stock_picking_obj     = self.pool.get('stock.picking')
        stock_move_obj     = self.pool.get('stock.move') 
        res_currency_obj     = self.pool.get('res.currency') 
        
        
        po_filter_selection = data['form']['po_filter_selection']
        curr_filter_selection = data['form']['curr_filter_selection']
          
        self.sortby_ids = data['form']['sortby_ids'] or False
         
        self.output_supp_header, self.supplier_ids = self._search_data(self.cr, self.uid, ids, self.pool.get('res.partner'),
                                                                                      [],
                                                                                      data['form']['supp_filter_selection'],
                                                                                      data['form']['supp_name_def_from'] and data['form']['supp_name_def_from'][0] or False,
                                                                                      data['form']['supp_name_def_to'] and data['form']['supp_name_def_to'][0] or False,
                                                                                      data['form']['supp_name_input_from'] or False,
                                                                                      data['form']['supp_name_input_to'] or False,
                                                                                      data['form']['partner_ids'] or False,
                                                                                      context=context)
        
        self.output_grn_header, self.grn_no_ids = self._search_data(self.cr, self.uid, ids, self.pool.get('stock.picking'),
                                                                                      [('state','=','done')],
                                                                                      data['form']['grn_filter_selection'],
                                                                                      data['form']['grn_no_def_from'] and data['form']['grn_no_def_from'][0] or False,
                                                                                      data['form']['grn_no_def_to'] and data['form']['grn_no_def_to'][0] or False,
                                                                                      data['form']['grn_no_input_from'] or False,
                                                                                      data['form']['grn_no_input_to'] or False,
                                                                                      data['form']['grn_ids'] or False,
                                                                                      context=context)
   

        date_from = data['form']['date_from']
        date_to = data['form']['date_to']
        
        output_date_header = ''
        val_date = []
        if data['form']['date_filter_selection'] == 'date':
            if date_from and not date_to:
                output_date_header = 'Date Start From : %s' % (date_from,)
                val_date.append(('date_done','>=',str(date_from)))
            elif date_to and not date_from:
                output_date_header = 'Date Until : %s' % (date_to,)
                val_date.append(('date_done','<=',str(date_to))) 
            elif date_to and date_from:
                output_date_header = 'Date Start From : %s Until: %s' % (date_from, date_to)
                val_date.append(('date_done','>=',str(date_from)))
                val_date.append(('date_done','<=',str(date_to)))
        
         
        po_no_def_from = data['form']['po_no_def_from'] and data['form']['po_no_def_from'][0] or False
        po_no_def_to = data['form']['po_no_def_to'] and data['form']['po_no_def_to'][0] or False     
        po_no_input_from = data['form']['po_no_input_from'] or False
        po_no_input_to = data['form']['po_no_input_to'] or False
        po_ids = data['form']['po_ids'] or False
        
        val_data =[]  
        stock_picking_ids = []
        data_header = ''   
        if po_filter_selection == 'def':
            data_found = False 
            if po_no_def_from :
                po_from_stock_move_ids = purchase_order_obj.search(self.cr, self.uid, [('id', '=', po_no_def_from)])
                default_from_header = purchase_order_obj.browse(self.cr, self.uid, po_from_stock_move_ids).name
                data_found = True 
                val_data.append(('purchase_line_id.order_id.name', '>=', default_from_header)) 
            if po_no_def_to :
                po_to_stock_move_ids = purchase_order_obj.search(self.cr, self.uid, [('id', '=', po_no_def_to)])
                default_to_header = purchase_order_obj.browse(self.cr, self.uid, po_to_stock_move_ids).name
                data_found = True 
                val_data.append(('purchase_line_id.order_id.name', '<=', default_to_header)) 
            if data_found:
                stock_p_ids = []
                data_header = '"' + default_from_header + '" - "' + default_to_header + '"'
                data_stock_move_po_ids = stock_move_obj.search(self.cr, self.uid, val_data,order='id ASC')  
                for sp in stock_move_obj.browse(self.cr, self.uid, data_stock_move_po_ids) :
                    stock_p_ids.append((sp.picking_id.id)) 
                stock_picking_ids = stock_p_ids 
        if po_filter_selection == 'input':
            data_found = False 
            if po_no_input_from:   
                data_ids_from = purchase_order_obj.search(self.cr, self.uid, [('name','=ilike',po_no_input_from + '%')], order="name", limit=1)
                if data_ids_from:
                    input_from_name = purchase_order_obj.browse(self.cr, self.uid, data_ids_from[0]).name 
                    data_found = True
                    val_data.append(('purchase_line_id.order_id.name', '>=', input_from_name))
            if po_no_input_to:    
                data_ids_to = purchase_order_obj.search(self.cr, self.uid, [('name','=ilike', po_no_input_to + '%')], order="name desc", limit=1)
                if data_ids_to:
                    input_to_name = purchase_order_obj.browse(self.cr, self.uid, data_ids_to[0]).name
                    data_found = True
                    val_data.append(('purchase_line_id.order_id.name', '<=', input_to_name)) 
            data_header = '"' + po_no_input_from + '" - "' + po_no_input_to + '"'
            if data_found:
                stock_p_ids = []
                data_stock_move_po_ids = stock_move_obj.search(self.cr, self.uid, val_data,order='id ASC')  
                for sp in stock_move_obj.browse(self.cr, self.uid, data_stock_move_po_ids) :
                    stock_p_ids.append((sp.picking_id.id)) 
                stock_picking_ids = stock_p_ids
        if po_filter_selection == 'selection':
            if po_ids:
                sel_ids = ''
                stock_p_ids = [] 
                for sel in  purchase_order_obj.browse(self.cr, self.uid, po_ids):
                    sel_ids += ('"%s",')%(sel.name,) 
                data_header = '[' + sel_ids +']'
                data_stock_move_po_ids = stock_move_obj.search(self.cr, self.uid, [('purchase_line_id.order_id.id', 'in', po_ids)])
                for sp in stock_move_obj.browse(self.cr, self.uid, data_stock_move_po_ids) :
                    stock_p_ids.append((sp.picking_id.id)) 
                stock_picking_ids = stock_p_ids
        
         
        curr_name_def_from = data['form']['curr_name_def_from'] and data['form']['curr_name_def_from'][0] or False
        curr_name_def_to = data['form']['curr_name_def_to'] and data['form']['curr_name_def_to'][0] or False     
        curr_name_input_from = data['form']['curr_name_input_from'] or False
        curr_name_input_to = data['form']['curr_name_input_to'] or False
        currency_ids = data['form']['currency_ids'] or False
        
        val_data_curr =[]  
        curr_ids = []
        data_header_curr = ''   
        if curr_filter_selection == 'def':
            data_found = False 
            if curr_name_def_from :
                curr_from_stock_move_ids = res_currency_obj.search(self.cr, self.uid, [('id', '=', curr_name_def_from)])
                default_from_header = res_currency_obj.browse(self.cr, self.uid, curr_from_stock_move_ids).name
                data_found = True 
                val_data_curr.append(('purchase_line_id.order_id.currency_id.name', '>=', default_from_header)) 
            if curr_name_def_to :
                curr_to_stock_move_ids = res_currency_obj.search(self.cr, self.uid, [('id', '=', curr_name_def_to)])
                default_to_header = res_currency_obj.browse(self.cr, self.uid, curr_to_stock_move_ids).name
                data_found = True 
                val_data_curr.append(('purchase_line_id.order_id.currency_id.name', '<=', default_to_header)) 
            if data_found:
                currency_at_po_ids = []
                data_header_curr = '"' + default_from_header + '" - "' + default_to_header + '"'
                data_stock_move_currency_ids = stock_move_obj.search(self.cr, self.uid, val_data_curr,order='id ASC')  
                for curr in stock_move_obj.browse(self.cr, self.uid, data_stock_move_currency_ids) :
                    currency_at_po_ids.append((curr.picking_id.id)) 
                curr_ids = currency_at_po_ids 
        if curr_filter_selection == 'input':
            data_found = False 
            if curr_name_input_from:   
                data_ids_from = res_currency_obj.search(self.cr, self.uid, [('name','=ilike',curr_name_input_from + '%')], order="name", limit=1)
                if data_ids_from:
                    input_from_name = res_currency_obj.browse(self.cr, self.uid, data_ids_from[0]).name 
                    data_found = True
                    val_data_curr.append(('purchase_line_id.order_id.currency_id.name', '>=', input_from_name))
            if curr_name_input_to:    
                data_ids_to = res_currency_obj.search(self.cr, self.uid, [('name','=ilike', curr_name_input_to + '%')], order="name desc", limit=1)
                if data_ids_to:
                    input_to_name = res_currency_obj.browse(self.cr, self.uid, data_ids_to[0]).name
                    data_found = True
                    val_data_curr.append(('purchase_line_id.order_id.currency_id.name', '<=', input_to_name)) 
            data_header_curr = '"' + curr_name_input_from + '" - "' + curr_name_input_to + '"'
            if data_found:
                currency_at_po_ids = []
                data_stock_move_currency_ids = stock_move_obj.search(self.cr, self.uid, val_data_curr,order='id ASC')  
                for curr in stock_move_obj.browse(self.cr, self.uid, data_stock_move_currency_ids) :
                    currency_at_po_ids.append((curr.picking_id.id)) 
                curr_ids = currency_at_po_ids
        if curr_filter_selection == 'selection':
            if currency_ids:
                sel_ids = ''
                currency_stock_picking_ids = [] 
                for sel in  res_currency_obj.browse(self.cr, self.uid, currency_ids):
                    sel_ids += ('"%s",')%(sel.name,) 
                data_header_curr = '[' + sel_ids +']'
                data_stock_move_currency_ids = stock_move_obj.search(self.cr, self.uid, [('purchase_line_id.order_id.currency_id.id', 'in', currency_ids)])
                for curr in stock_move_obj.browse(self.cr, self.uid, data_stock_move_currency_ids) :
                    currency_stock_picking_ids.append((curr.picking_id.id)) 
                curr_ids = currency_stock_picking_ids
                  
        self.data_stock_picking_curr_ids=curr_ids
        self.data_stock_picking_curr_header=data_header_curr 
        
        self.data_stock_picking_po_ids=stock_picking_ids
        self.data_stock_picking_po_header=data_header 
        
        self.po_filter_selection = po_filter_selection
        self.curr_filter_selection = curr_filter_selection
        
        self.output_date_header = output_date_header
        self.val_date = val_date
              
        return super(receiving_report_pdf, self).set_context(objects, data, new_ids)

    def __init__(self, cr, uid, name, context=None):
        super(receiving_report_pdf, self).__init__(cr, uid, name, context=context)
        self.report_total = 0.00
        self.balance_by_cur = {}
        self.uid=uid
        self.localcontext.update({
            'time': time,
            'locale': locale,
            'get_lines': self._get_lines,
            'get_header_title': self._get_header, 
            'get_printed_date' : self._get_printed_date,  
            'get_decimal_accuracy_account': self._get_decimal_accuracy_account,
            'get_decimal_accuracy_product_price': self._get_decimal_accuracy_product_price,
            'get_decimal_accuracy_uom': self._get_decimal_accuracy_uom,
            'get_printed_by': self._get_printed_by,
            'get_output_po_header': self._get_output_po_header,
            'get_output_grn_header': self._get_output_grn_header,
            'get_output_supp_header': self._get_output_supp_header,
            'get_output_date_header': self._get_output_date_header,
            'get_output_sortby_header': self._get_output_sortby_header,
            'get_output_curr_header': self._get_output_curr_header,
            })
 
    def _get_printed_date(self):
        header = ''
        user_obj = self.pool.get('res.users')
        user_ids = user_obj.search(self.cr, self.uid, [('id','=',self.uid)])
        if user_ids :
            tz = user_obj.browse(self.cr, self.uid, user_ids[0])
            tz_name = tz.tz
        os.environ['TZ'] = tz_name #set time zone secara otomatis tidak hard code
        time.tzset()
        header = 'Printed date : ' + time.strftime("%Y/%m/%d") + '  Time : '+ time.strftime("%H:%M:%S")
         
        return header
    
    def _get_printed_by(self):
        header =''
        user_obj = self.pool.get('res.users')
        user_ids = user_obj.search(self.cr, self.uid, [('id','=',self.uid)])
        if user_ids :
            user_id = user_obj.browse(self.cr, self.uid, user_ids[0])
            user_name = user_id.name
        
        header = 'Printed by : ' +user_name
        
        return header
    
    def _get_output_po_header(self):
        header = ''
        if self.data_stock_picking_po_header:
            header = 'Purhcase Order : ' + self.data_stock_picking_po_header
         
        return header
    
    def _get_output_grn_header(self):
        header = ''
        if self.output_grn_header:
            header = 'GRN : ' + self.output_grn_header
         
        return header
    
    def _get_output_supp_header(self):
        header = ''
        if self.output_supp_header:
            header = 'Supplier : ' + self.output_supp_header
         
        return header
     
    def _get_output_date_header(self):
        header = ''
        if self.output_date_header:
            header = self.output_date_header
         
        return header
    
    def _get_output_curr_header(self):
        header = ''
        if self.data_stock_picking_curr_header:
            header = 'Currency : ' +self.data_stock_picking_curr_header
         
        return header
    
    def _get_output_sortby_header(self):
        header = output_sortby_header = ''
        result = []
        receive_sortby_ids = ""
        if self.sortby_ids:
            receive_sortby_ids = self.pool.get('receiving.sortby').search(self.cr, self.uid, [('id', 'in', self.sortby_ids)], order='seq desc')
        
        if receive_sortby_ids:
            for item in self.pool.get('receiving.sortby').browse(self.cr, self.uid, receive_sortby_ids):
                result.append({
                        'seq' : item['seq'],
                        'sort_by' : item['sort_by'],
                        })
            result = result and sorted(result, key=lambda val_res: val_res['seq']) or []               
            
            for rs in result:
                sort_name = ''
                if rs['sort_by'] == 'date_done':
                    sort_name = 'Receive Date'
                elif rs['sort_by'] == 'origin':
                    sort_name = 'PO No.'
                elif rs['sort_by'] == 'name':
                    sort_name = 'GRN No.'
                elif rs['sort_by'] == 'partner_id':
                    sort_name = 'Supplier'
                elif rs['sort_by'] == 'curr_name' :  
                    sort_name = 'Currency '     
                output_sortby_header += ('"%s",')%(sort_name,)
            header = 'Sort By : ' + output_sortby_header

        return header
    
    def _get_decimal_accuracy_account(self):
        dp = 2
        dp_obj = self.pool.get('decimal.precision')
        dp_ids = dp_obj.search(self.cr, self.uid, [('name','=','Account')])
        if dp_ids :
            dp_id = dp_obj.browse(self.cr, self.uid, dp_ids[0])
            dp = dp_id.digits
        return dp
    
    def _get_decimal_accuracy_product_price(self):
        dp = 5
        dp_obj = self.pool.get('decimal.precision')
        dp_ids = dp_obj.search(self.cr, self.uid, [('name','=','Product Price')])
        if dp_ids :
            dp_id = dp_obj.browse(self.cr, self.uid, dp_ids[0])
            dp = dp_id.digits
        return dp
    
    def _get_decimal_accuracy_uom(self):
        dp = 3
        dp_obj = self.pool.get('decimal.precision')
        dp_ids = dp_obj.search(self.cr, self.uid, [('name','=','Product Unit of Measure')])
        if dp_ids :
            dp_id = dp_obj.browse(self.cr, self.uid, dp_ids[0])
            dp = dp_id.digits
        return dp   
     
    def _get_header(self):
        header = 'Receiving Report'
        return header
      
    def _get_lines(self):
        cr              = self.cr
        uid             = self.uid
        purchase_order_obj      = self.pool.get('purchase.order')
        stock_picking_obj     = self.pool.get('stock.picking')
        stock_move_obj     = self.pool.get('stock.move') 
        partner_obj     = self.pool.get('res.partner')
        company_obj = self.pool.get('res.company')
        currency_obj = self.pool.get('res.currency')
        purchase_orderline_obj    = self.pool.get('purchase.order.line')
        receiving_sortby_obj = self.pool.get('receiving.sortby')
        val_receive = []
        results1        = []
#         val_part = self.val_part 
          
        data_stock_picking_po_ids = self.data_stock_picking_po_ids
        supplier_ids = self.supplier_ids
        grn_no_ids = self.grn_no_ids
        val_date = self.val_date
        data_stock_picking_curr_ids=self.data_stock_picking_curr_ids
         
        
        val_receive.append(('state','=','done'))
        val_receive.append(('picking_type_id','=',1))
        
        if data_stock_picking_po_ids:
            val_receive.append(('id','in',data_stock_picking_po_ids))
        if supplier_ids:
            val_receive.append(('partner_id','in',supplier_ids)) 
        if grn_no_ids: 
            val_receive.append(('id','in',grn_no_ids))
        if data_stock_picking_curr_ids:
            val_receive.append(('id','in',data_stock_picking_curr_ids))
        if val_date:
            val_receive += val_date 
        
        
        receiving_sortby_ids = []
        if self.sortby_ids:
            receiving_sortby_ids = receiving_sortby_obj.search(cr, uid, [('id', 'in', self.sortby_ids)], order='seq desc')
        
        stock_picking_ids=stock_picking_obj.search(cr, uid,val_receive)
         
        for stock_pickingg in stock_picking_obj.browse(cr, uid, stock_picking_ids, context=None):
            
            move_lines = []
            curr_name = ''
            total = 0
            move_lines_ids=stock_move_obj.search(cr, uid,[('picking_id','=',stock_pickingg.id)])
            for stock_move_line in stock_move_obj.browse(cr, uid, move_lines_ids, context=None) :
                 move_lines.append({ 
                   'description' : stock_move_line.name,
                   'product_qty' : stock_move_line.product_uom_qty,
                   'currency_name': stock_move_line.purchase_line_id.order_id.currency_id.name,
                   'price_unit': stock_move_line.purchase_line_id.price_unit,
                   'subtotal': (stock_move_line.product_uom_qty * stock_move_line.purchase_line_id.price_unit), 
                   })
                 total += (stock_move_line.product_uom_qty * stock_move_line.purchase_line_id.price_unit)
                 curr_name =  stock_move_line.purchase_line_id.order_id.currency_id.name
            results1.append({
                    'date_done' : stock_pickingg.date_done[:10],        
                    'origin' : stock_pickingg.origin,
                    'name' :stock_pickingg.name,
                    'partner_id': stock_pickingg.partner_id.name, 
                    'curr_name' : curr_name, 
                    'move_lines': move_lines,
                    'total': total,
                    })
            
        if receiving_sortby_ids:
            for receiving_sortby in receiving_sortby_obj.browse(cr, uid, receiving_sortby_ids):
                results1 = results1 and sorted(results1, key=lambda val_res: val_res[receiving_sortby.sort_by]) or []
        else:
            results1 = results1 and sorted(results1, key=lambda val_res: val_res['curr_name']) or []
            results1 = results1 and sorted(results1, key=lambda val_res: val_res['partner_id']) or []
            results1 = results1 and sorted(results1, key=lambda val_res: val_res['name']) or []
            results1 = results1 and sorted(results1, key=lambda val_res: val_res['origin']) or []
            results1 = results1 and sorted(results1, key=lambda val_res: val_res['date_done']) or []
                          
#         results1 = results1 and sorted(results1, key=lambda val_res: val_res['date_done']) or []
         
        return results1  
    
    
report_sxw.report_sxw('report.receiving.report.pdf', 'stock.picking',
'addons/batam_fast_module/stock/report/report/receiving_report_pdf.rml', parser=receiving_report_pdf, header=False)
   
         
        
